﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using Newtonsoft.Json;

namespace ExcelJsonParser
{
    public class JsonUndefined
    {
    }
    public enum JsonValueTypes { String, Null, Undefined, Bool, Int, Double, JsonObject, JsonArray };
    public class JsonWorkCell
    {
        public static JsonUndefined jsonUndefined { get { return _jsonUndefined;} }
        private static JsonUndefined _jsonUndefined = new JsonUndefined();
        public static object GetJsonValueFromCell(Range cell)
        {
            if ("@".Equals(cell.NumberFormat))
            {
                string returnString = cell.Text;
                return returnString;
            }
            if ("General".Equals(cell.NumberFormat))
            {
                if ("NULL".Equals(cell.Text.ToUpper()))
                {
                    return null;
                }
                if (cell.Value == null)
                {
                    return _jsonUndefined;
                }
                bool boolParseResult = false;
                if (Boolean.TryParse(cell.Value.ToString(), out boolParseResult))
                {
                    return boolParseResult;
                }
                Int64 int64ParseResult;
                if (Int64.TryParse(cell.Value.ToString(), out int64ParseResult))
                {
                    return int64ParseResult;
                }
                Double doubleParseResult;
                if (Double.TryParse(cell.Value.ToString(), out doubleParseResult))
                {
                    return doubleParseResult;
                }
                try
                {
                    object parsedObj = JavaScriptConvert.DeserializeObject(cell.Value.ToString());
                    if (parsedObj is JavaScriptArray || parsedObj is JavaScriptObject)
                    {
                        return parsedObj;
                    }
                }
                catch (Exception)
                {
                }
            }
            if ("".Equals(cell.Text))
            {
                return null;
            }
            return cell.Text;
        }

        public static JsonValueTypes GetJsonTypeFromCell(Range cell, out object javaOjbect)
        {
            if (cell.Rows.Count == 1 && cell.Columns.Count == 1)
            {
                javaOjbect = GetJsonValueFromCell(cell);
                if (javaOjbect == null)
                {
                    return JsonValueTypes.Null;
                }
                if (javaOjbect is JsonUndefined)
                {
                    return JsonValueTypes.Undefined;
                }
                if (javaOjbect is Boolean)
                {
                    return JsonValueTypes.Bool;
                }
                if (javaOjbect is Int64)
                {
                    return JsonValueTypes.Int;
                }
                if (javaOjbect is Double)
                {
                    return JsonValueTypes.Double;
                }
                if (javaOjbect is JavaScriptArray)
                {
                    return JsonValueTypes.JsonArray;
                }
                if (javaOjbect is JavaScriptObject)
                {
                    return JsonValueTypes.JsonObject;
                }
                if (javaOjbect is string)
                {
                    return JsonValueTypes.String;
                }
            }
            javaOjbect = null;
            return JsonValueTypes.Null;
        }

        public static void SetCellByJson(Range cell, object javaObject)
        {
            if (javaObject == null)
            {
                cell.NumberFormat = "General";
                cell.Value = "NULL";
            }
            else
            {
                switch (javaObject.GetType().Name)
                {
                    case "String":
                        cell.NumberFormat = "@";
                        cell.Value = javaObject;
                        break;
                    case "Int64":
                        cell.NumberFormat = "General";
                        cell.Value = javaObject;
                        break;
                    case "Double":
                        cell.NumberFormat = "General";
                        cell.Value = javaObject;
                        break;
                    case "JavaScriptArray":
                        cell.NumberFormat = "General";
                        cell.Value = JavaScriptConvert.SerializeObject(javaObject);
                        break;
                    case "JavaScriptObject":
                        cell.NumberFormat = "General";
                        cell.Value = JavaScriptConvert.SerializeObject(javaObject);
                        break;
                    case "Boolean":
                        cell.NumberFormat = "General";
                        cell.Value = javaObject;
                        break;
                    case "JsonUndefined":
                        cell.NumberFormat = "General";
                        cell.Value = null;
                        break;
                    default:
                        break;
                }
            }
        }

        internal static void ConvertJsonValueTypeOfCell(Range cell, object p)
        {
            if (cell.Rows.Count == 1 && cell.Columns.Count == 1)
            {
                if (p == null)
                {
                    cell.NumberFormat = "General";
                    cell.Value = "NULL";
                }
                else
                {
                    if (p is JsonUndefined)
                    {
                        cell.NumberFormat = "General";
                        cell.Value = null;
                    }
                    else
                    {
                        Type type = p as Type;
                        switch (type.Name)
                        {
                            case "String":
                                cell.NumberFormat = "@";
                                break;
                            case "Int64":
                                cell.NumberFormat = "General";
                                break;
                            case "Double":
                                cell.NumberFormat = "General";
                                break;
                            case "JavaScriptArray":
                                cell.NumberFormat = "General";
                                break;
                            case "JavaScriptObject":
                                cell.NumberFormat = "General";
                                break;
                            case "Boolean":
                                cell.NumberFormat = "General";
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
    }
}
